<?php

namespace App\Services\Wallet;

use App\Constant\Enum;
use App\Models\User;
use App\Models\UserWallet;
use App\Models\UserWalletActive;
use App\Models\UserWithdraw;
use Illuminate\Support\Carbon;

class UserWalletService
{
    public static function outcome(UserWithdraw $userWithdraw, int $amount, string $account = ''): UserWallet
    {
        /** @var User $user */
        $user = $userWithdraw->user;
        /** @var UserWallet $wallet */
        $wallet = $user->wallet()->first();
        if (empty($wallet)) {
            throw new \Exception('用户账户异常');
        }
        $beforeRewardCoins = $wallet->reward_coins;
        $beforeCommissionCoins = $wallet->commission_coins;
        if ($account == Enum::WALLET_TYPE_COMMISSION) {
            // 扣除佣金
            $d1 = (int)($wallet->commission_coins - $amount);
            $walletType = Enum::WALLET_TYPE_COMMISSION;

            $afterCommissionCoins = $d1;
            $afterRewardCoins = $beforeRewardCoins;
        } else {
            // 优先扣除收益
            $d1 = (int)($wallet->reward_coins - $amount);
            if ($d1 < 0) {
                $d2 = $wallet->commission_coins + $d1;
                $afterRewardCoins = 0;
                $afterCommissionCoins = max($d2, 0);
                $walletType = Enum::WALLET_TYPE_REWARD;
            } else {
                $afterRewardCoins = $d1;
                $afterCommissionCoins = $beforeCommissionCoins;
                $walletType = Enum::WALLET_TYPE_REWARD;
            }
        }
        //提现中金币
        $wallet->update([
            'on_withdraw' => 1,
            'user_withdraw_id' => $userWithdraw->getAttribute('id'),
            'locked_coins' => $amount
        ]);
        $active = [
            'user_id' => $user->getAttribute('id'),
            'user_withdraw_id' => $userWithdraw->getAttribute('id'),
            'action' => Enum::WALLET_ACTIVE_ACTION_OUTCOME,
            'wallet_type' => $walletType,
            'coins' => $amount,
            'before_reward_coins' => $beforeRewardCoins,
            'after_reward_coins' => $afterRewardCoins,
            'before_commission_coins' => $beforeCommissionCoins,
            'after_commission_coins' => $afterCommissionCoins,
            'status' => Enum::WALLET_ACTIVE_STATUS_PENDING,
            'changed_at' => Carbon::now(),
        ];
        UserWalletActive::query()->create($active);

        return $wallet;
    }

    public static function income(User $user, int $amount, string $walletType): UserWallet
    {
        $wallet = $user->wallet()->first();
        if (empty($wallet)) {
            $wallet = $user->wallet()->create([
                'reward_coins' => 0,
                'commission_coins' => 0,
            ]);
        }

        // reward_coins, commission_coins
        $history = $wallet->toArray();
        //区分用户激励  团长奖励,统一写入用户奖励
//        if (in_array($walletType, [
//            Enum::WALLET_TYPE_REWARD,
//            Enum::WALLET_TYPE_COMMISSION,
//            Enum::WALLET_TYPE_REFUND,
//            Enum::WALLET_TYPE_TASK
//        ]))
//统一写入用户奖励
        if (1) {
            $actives = [
                'user_id' => $user->getAttribute('id'),
                'operator_id' => 0,
                'wallet_type' => $walletType,
                'action' => Enum::WALLET_ACTIVE_ACTION_INCOME,
                'coins' => $amount,
                'before_reward_coins' => $history['reward_coins'],
                'after_reward_coins' => $history['reward_coins'] + $amount,
                'status' => Enum::WALLET_ACTIVE_STATUS_APPROVED,
                'changed_at' => Carbon::now(),
            ];
            $walletAttributes = [
                'reward_coins' => $history['reward_coins'] + $amount,
            ];
        } else {
            $actives = [
                'user_id' => $user->getAttribute('id'),
                'operator_id' => 0,
                'wallet_type' => $walletType,
                'action' => Enum::WALLET_ACTIVE_ACTION_INCOME,
                'coins' => $amount,
                'status' => Enum::WALLET_ACTIVE_STATUS_APPROVED,
                'before_commission_coins' => $history['commission_coins'],
                'after_commission_coins' => $history['commission_coins'] + $amount,
                'changed_at' => Carbon::now(),
            ];
            $walletAttributes = [
                'commission_coins' => $history['commission_coins'] + $amount,
            ];
        }
        UserWallet::query()->where('user_id', $user->getAttribute('id'))->update($walletAttributes);
        UserWalletActive::query()->create($actives);

        return $user->wallet;
    }


    public static function getUserAllCoins(User $user)
    {
        $wallet = $user->wallet()->first();

        return ($wallet->reward_coins ?? 0) + ($wallet->commission_coins ?? 0);
    }

    public static function getUserWithdrawCoins(User $user)
    {
        $wallet = $user->wallet()->first();

        return max($wallet->locked_coins, 0);
    }

    public static function getUserWithdrawsum(User $user)
    {


        return $user->userwithdraws()->sum('money');
    }

    public static function getWithdrawableCoins(User $user)
    {
        $wallet = $user->wallet()->first();
        $total = ($wallet->reward_coins ?? 0) + ($wallet->commission_coins ?? 0);

        return max($total - $wallet->locked_coins, 0);
    }

    public static function getTodayCoins(User $user)
    {
        $aggregate = UserWalletActive::query()
            ->where(['user_id' => $user->getAttribute('id')])
            ->where(['action' => Enum::WALLET_ACTIVE_ACTION_INCOME])
            ->whereBetween('changed_at', [
                Carbon::today()->startOfDay(),
                Carbon::today()->endOfDay(),
            ])
            ->selectRaw("sum(coins) as today_coins")
            ->first();

        return (int)$aggregate->today_coins ?? 0;
    }

    public static function getYesterdayCoins(User $user)
    {
        $aggregate = UserWalletActive::query()
            ->where(['user_id' => $user->getAttribute('id')])
            ->where(['action' => Enum::WALLET_ACTIVE_ACTION_INCOME])
            ->whereBetween('changed_at', [
                Carbon::yesterday()->startOfDay(),
                Carbon::yesterday()->endOfDay(),
            ])
            ->selectRaw("sum(coins) as yesterday_coins")
            ->first();

        return (int)$aggregate->yesterday_coins ?? 0;
    }
}
